﻿using System;
using System.Threading;
using l1cs.server.datatables;
using l1cs.server.model;
using l1cs.server.model.Instance;
using l1cs.server.serverpackets;
using l1cs.server.templates;

namespace l1cs.server
{
    public class AuctionTimeController
    {
        private static Logger _log = Logger.getLogger( typeof( AuctionTimeController ).FullName );

        private static AuctionTimeController _instance;

        public static AuctionTimeController getInstance()
        {
            if ( _instance == null )
            {
                _instance = new AuctionTimeController();
            }
            return _instance;
        }

        public void threadSub( Object state )
        {
            while ( true )
            {
                checkAuctionDeadline();
                Thread.Sleep( 60000 );
            }
        }

        private void checkAuctionDeadline()
        {
            AuctionBoardTable boardTable = new AuctionBoardTable();
            foreach ( L1AuctionBoard board in boardTable.getAuctionBoardTableList() )
            {
                TimeSpan timeSpan = board.getDeadline() - DateTime.Now;
                if ( timeSpan.TotalSeconds < 0 )
                {
                    endAuction( board );
                }
            }
        }

        private void endAuction( L1AuctionBoard board )
        {
            int houseId = board.getHouseId();
            int price = board.getPrice();
            int oldOwnerId = board.getOldOwnerId();
            String bidder = board.getBidder();
            int bidderId = board.getBidderId();

            if ( oldOwnerId != 0 && bidderId != 0 )
            {
                // 以前の所有者あり・落札者あり
                L1PcInstance oldOwnerPc = (L1PcInstance)L1World.getInstance().findObject( oldOwnerId );
                int payPrice = (int)( price * 0.9 );
                if ( oldOwnerPc != null )
                {
                    // 以前の所有者がオンライン中
                    oldOwnerPc.getInventory().storeItem( L1ItemId.ADENA, payPrice );
                    // あなたが所有していた家が最終価格%1アデナで落札されました。%n
                    // 手数料10%%を除いた残りの金額%0アデナを差し上げます。%nありがとうございました。%n%n
                    oldOwnerPc.sendPackets( new S_ServerMessage( 527, Convert.ToString( payPrice ) ) );
                }
                else
                {
                    // 以前の所有者がオフライン中
                    L1ItemInstance item = ItemTable.getInstance().createItem( L1ItemId.ADENA );
                    item.setCount( payPrice );
                    CharacterItemsTable.storeItem( oldOwnerId, item );
                }

                L1PcInstance bidderPc = (L1PcInstance)L1World.getInstance()
                        .findObject( bidderId );
                if ( bidderPc != null )
                {
                    // 落札者がオンライン中
                    // おめでとうございます。%nあなたが参加された競売は最終価格%0アデナの価格で落札されました。%n
                    // 様がご購入された家はすぐにご利用できます。%nありがとうございました。%n%n
                    bidderPc.sendPackets( new S_ServerMessage( 524, Convert.ToString( price ), bidder ) );
                }
                deleteHouseInfo( houseId );
                setHouseInfo( houseId, bidderId );
                deleteNote( houseId );
            }
            else if ( oldOwnerId == 0 && bidderId != 0 )
            {
                // 以前の所有者なし・落札者あり
                L1PcInstance bidderPc = (L1PcInstance)L1World.getInstance()
                        .findObject( bidderId );
                if ( bidderPc != null )
                {
                    // 落札者がオンライン中
                    // おめでとうございます。%nあなたが参加された競売は最終価格%0アデナの価格で落札されました。%n
                    // 様がご購入された家はすぐにご利用できます。%nありがとうございました。%n%n
                    bidderPc.sendPackets( new S_ServerMessage( 524, Convert.ToString( price ), bidder ) );
                }
                setHouseInfo( houseId, bidderId );
                deleteNote( houseId );
            }
            else if ( oldOwnerId != 0 && bidderId == 0 )
            {
                // 以前の所有者あり・落札者なし
                L1PcInstance oldOwnerPc = (L1PcInstance)L1World.getInstance()
                        .findObject( oldOwnerId );
                if ( oldOwnerPc != null )
                {
                    // 以前の所有者がオンライン中
                    // あなたが申請なさった競売は、競売期間内に提示した金額以上での支払いを表明した方が現れなかったため、結局取り消されました。%n
                    // 従って、所有権があなたに戻されたことをお知らせします。%nありがとうございました。%n%n
                    oldOwnerPc.sendPackets( new S_ServerMessage( 528 ) );
                }
                deleteNote( houseId );
            }
            else if ( oldOwnerId == 0 && bidderId == 0 )
            {
                // 以前の所有者なし・落札者なし
                // 締め切りを5日後に設定し再度競売にかける
                board.setDeadline( DateTime.Today.AddDays( 5 ) );
                AuctionBoardTable boardTable = new AuctionBoardTable();
                boardTable.updateAuctionBoard( board );
            }
        }

        /// <summary>
        /// 以前の所有者のアジトを消す
        /// </summary>
        /// <param name="houseId">houseId</param>
        private void deleteHouseInfo( int houseId )
        {
            foreach ( L1Clan clan in L1World.getInstance().getAllClans() )
            {
                if ( clan.getHouseId() == houseId )
                {
                    clan.setHouseId( 0 );
                    ClanTable.getInstance().updateClan( clan );
                }
            }
        }

        /// <summary>
        /// 落札者のアジトを設定する
        /// </summary>
        /// <param name="houseId">houseId</param>
        /// <param name="bidderId">bidderId</param>
        private void setHouseInfo( int houseId, int bidderId )
        {
            foreach ( L1Clan clan in L1World.getInstance().getAllClans() )
            {
                if ( clan.getLeaderId() == bidderId )
                {
                    clan.setHouseId( houseId );
                    ClanTable.getInstance().updateClan( clan );
                    break;
                }
            }
        }

        /// <summary>
        /// アジトの競売状態をOFFに設定し、競売掲示板から消す
        /// </summary>
        /// <param name="houseId">houseId</param>
        private void deleteNote( int houseId )
        {
            // アジトの競売状態をOFFに設定する
            L1House house = HouseTable.getInstance().getHouseTable( houseId );
            house.setOnSale( false );
            house.setTaxDeadline( DateTime.Today.AddDays( Config.HOUSE_TAX_INTERVAL ) );
            HouseTable.getInstance().updateHouse( house );

            // 競売掲示板から消す
            AuctionBoardTable boardTable = new AuctionBoardTable();
            boardTable.deleteAuctionBoard( houseId );
        }

    }
}
